﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using Microsoft.Windows.Design.Interaction;
using Microsoft.Windows.Design.Model;
using System.Windows;
using System.Windows.Media;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Shapes;
using System.Windows.Data;
using C4F.VistaP2P.WPF.Network;
using C4F.VistaP2P.WPF.Chat;
using C4F.VistaP2P.WPF.File;
using C4F.VistaP2P.WPF.Picture;
using C4F.VistaP2P.WPF.Media;

namespace Peer2PeerControlLibraryWPF.VisualStudio.Design
{
    public class NetworkManagerAdornerProvider : PrimarySelectionAdornerProvider
    {
        // All adorners are placed in an AdornerPanel
        // for sizing and layout support.
        private AdornerPanel _PopupAdornerPanel = new AdornerPanel();
        private NetworkManagerDesignTimeControl _p2pControl = new NetworkManagerDesignTimeControl();
        private const float ButtonSize = 30;
        private const float NudgeAmount = 10;
        private const float PaintCanSizeFactor = 0.7f;

        public NetworkManagerAdornerProvider()
        {

            // Create the button
            BouncyButton adorner = new BouncyButton();
            adorner.Click += new RoutedEventHandler(OnButtonClick);

            //Rectangle adorner = new Rectangle();
            adorner.Width = ButtonSize;
            adorner.Height = ButtonSize;
            adorner.Background = Brushes.Blue;
            //adorner.Fill = Brushes.Plum;
            Button b = new Button();
            b.Width = 0;
            b.Height =0;
            b.Visibility = Visibility.Hidden;

            FrameworkElement paintCan = b;//ImageResources.GetElement("PaintBucket.xaml");
            paintCan.Width = ButtonSize * PaintCanSizeFactor;
            paintCan.Height = ButtonSize * PaintCanSizeFactor;

            // Populate it with the paint can graphic and hook into its Click event
            adorner.Content = paintCan;

            // Position the adoner
            AdornerPlacementCollection placement = new AdornerPlacementCollection();

            // these ones are Relative to Adorner since the size and position is based on the
            // size of the adorner itself (i.e. I want it to be the desired size and position it
            // so that it is on the outside corner of the adorned element plus some nudge amount
            // NOTE: Coordinate space starts at 0,0 for the adorned element
            placement.SizeRelativeToAdornerDesiredHeight(1.0, 0);
            placement.SizeRelativeToAdornerDesiredWidth(1.0, 0);
            placement.PositionRelativeToAdornerHeight(-1, -NudgeAmount);
            placement.PositionRelativeToAdornerWidth(-1, -NudgeAmount);
            AdornerPanel.SetPlacements(adorner, placement);
            _p2pControl.ClosePopup += new RoutedEventHandler(_p2pControl_ClosePopup);
            
            
            // Position the popup
            AdornerPlacementCollection popupPlacement = new AdornerPlacementCollection();
            popupPlacement.SizeRelativeToAdornerDesiredHeight(1.0, 0);
            popupPlacement.SizeRelativeToAdornerDesiredWidth(1.0, 0);
            popupPlacement.PositionRelativeToAdornerHeight(-1, 0, adorner);
            popupPlacement.PositionRelativeToAdornerWidth(0, -NudgeAmount, adorner);
            AdornerPanel.SetPlacements(_p2pControl, popupPlacement);
            AdornerProperties.SetOrder(_PopupAdornerPanel, AdornerOrder.Foreground);          

            // And add it to the list of AdornerPanels provided by this AdornerProvider
            _PopupAdornerPanel.Children.Add(adorner);

            // Finally, add our panel to the Adorners collection
            Adorners.Add(_PopupAdornerPanel);
        }

        void _p2pControl_ClosePopup(object sender, RoutedEventArgs e)
        {
            

            ModelItem adornedElementModelItem = AdornerProperties.GetModel(_p2pControl);
            if (null != adornedElementModelItem)
            {
                ModelItem parentModelItem = adornedElementModelItem.Parent;
                ModelProperty siblingsProperty = parentModelItem.Properties["Children"];
                ModelItemCollection siblings = siblingsProperty.Collection;


                if (null != _p2pControl.Picture.SelectedValue)
                {
                    ModelItem binding = ModelFactory.CreateItem(Context, typeof(Binding));
                    binding.Properties["ElementName"].SetValue((string)_p2pControl.Picture.SelectedValue);
                    adornedElementModelItem.Properties[NetworkManager.PictureProperty].SetValue(binding);
                }


                if (null != _p2pControl.File.SelectedValue)
                {
                    ModelItem binding = ModelFactory.CreateItem(Context, typeof(Binding));
                    binding.Properties["ElementName"].SetValue((string)_p2pControl.File.SelectedValue);
                    adornedElementModelItem.Properties[NetworkManager.FileProperty].SetValue(binding);
                }


                if (null != _p2pControl.Chat.SelectedValue)
                {
                    ModelItem binding = ModelFactory.CreateItem(Context, typeof(Binding));
                    binding.Properties["ElementName"].SetValue((string)_p2pControl.Chat.SelectedValue);
                    adornedElementModelItem.Properties[NetworkManager.ChatProperty].SetValue(binding);
                }


                if (null != _p2pControl.Video.SelectedValue)
                {
                    ModelItem binding = ModelFactory.CreateItem(Context, typeof(Binding));
                    binding.Properties["ElementName"].SetValue((string)_p2pControl.Video.SelectedValue);
                    adornedElementModelItem.Properties[NetworkManager.VideoControlProperty].SetValue(binding);
                }

                if (null != _p2pControl.Audio.SelectedValue)
                {
                    ModelItem binding = ModelFactory.CreateItem(Context, typeof(Binding));
                    binding.Properties["ElementName"].SetValue((string)_p2pControl.Audio.SelectedValue);
                    adornedElementModelItem.Properties[NetworkManager.AudioControlProperty].SetValue(binding);
                }

                if (null != _p2pControl.UserName.SelectedValue)
                {
                    ModelItem binding = ModelFactory.CreateItem(Context, typeof(Binding));
                    binding.Properties["ElementName"].SetValue((string)_p2pControl.UserName.SelectedValue);
                    adornedElementModelItem.Properties[NetworkManager.UserNameProperty].SetValue(binding);
                }

                if (null != _p2pControl.NetworkName.SelectedValue)
                {
                    ModelItem binding = ModelFactory.CreateItem(Context, typeof(Binding));
                    binding.Properties["ElementName"].SetValue((string)_p2pControl.NetworkName.SelectedValue);
                    adornedElementModelItem.Properties[NetworkManager.NetworkNameProperty].SetValue(binding);
                }

                if (null != _p2pControl.PasswordName.SelectedValue)
                {
                    ModelItem binding = ModelFactory.CreateItem(Context, typeof(Binding));
                    binding.Properties["ElementName"].SetValue((string)_p2pControl.PasswordName.SelectedValue);
                    adornedElementModelItem.Properties[NetworkManager.PasswordProperty].SetValue(binding);
                }


                if (null != _p2pControl.SignInButton.SelectedValue)
                {
                    ModelItem binding = ModelFactory.CreateItem(Context, typeof(Binding));
                    binding.Properties["ElementName"].SetValue((string)_p2pControl.SignInButton.SelectedValue);
                    adornedElementModelItem.Properties[NetworkManager.SignInButtonProperty].SetValue(binding);
                }

                if (null != _p2pControl.Status.SelectedValue)
                {
                    ModelItem binding = ModelFactory.CreateItem(Context, typeof(Binding));
                    binding.Properties["ElementName"].SetValue((string)_p2pControl.Status.SelectedValue);
                    adornedElementModelItem.Properties[NetworkManager.StatusValueProperty].SetValue(binding);
                }


            }
        }

        // Called when the adorner Button is clicked
        private void OnButtonClick(object sender, RoutedEventArgs e)
        {
            if (_PopupAdornerPanel.Children.Contains(_p2pControl))
            {
                //already has this control visible, dont' do anything.
                return;
            }

            // add the popup panel
            ModelItem adornedElementModelItem = AdornerProperties.GetModel(_PopupAdornerPanel);
            
            ModelItem parentModelItem = adornedElementModelItem.Parent;
            //find the root under the window and get the collection of that
            while (parentModelItem.Parent != null)
            {
                if (parentModelItem.Parent.Parent != null)
                {
                    parentModelItem = parentModelItem.Parent;
                }
                else
                {
                    break;
                }
            }

            if (parentModelItem.ItemType.BaseType == typeof(Panel))
            {
                ModelProperty siblingsProperty = parentModelItem.Properties["Children"];
                ModelItemCollection siblings = siblingsProperty.Collection;
                _AddAllElements(adornedElementModelItem, siblings);
            }


            _PopupAdornerPanel.Children.Add(_p2pControl);
        }

        private void _AddAllElements(ModelItem adornedElementModelItem, ModelItemCollection siblings)
        {
            foreach (ModelItem mi in siblings)
            {
                Utility._AddItems(_p2pControl.Audio, mi, typeof(MediaControl), adornedElementModelItem, "Audio");
                Utility._AddItems(_p2pControl.Video, mi, typeof(MediaControl), adornedElementModelItem, "Video");
                Utility._AddItems(_p2pControl.Picture, mi, typeof(PictureControl), adornedElementModelItem, "Picture");
                Utility._AddItems(_p2pControl.File, mi, typeof(FileControl), adornedElementModelItem, "File");
                Utility._AddItems(_p2pControl.Chat, mi, typeof(ChatControl), adornedElementModelItem, "Chat");
                Utility._AddItems(_p2pControl.Status, mi, typeof(Label), adornedElementModelItem, "StatusValue");
                Utility._AddItems(_p2pControl.UserName, mi, typeof(TextBox), adornedElementModelItem, "UserName");
                Utility._AddItems(_p2pControl.NetworkName, mi, typeof(TextBox), adornedElementModelItem, "NetworkName");
                Utility._AddItems(_p2pControl.PasswordName, mi, typeof(TextBox), adornedElementModelItem, "Password");
                Utility._AddItems(_p2pControl.SignInButton, mi, typeof(Button), adornedElementModelItem, "SignInButton");

                if (mi.ItemType.BaseType == typeof(Panel))
                {
                    ModelProperty siblingsProperty = mi.Properties["Children"];
                    _AddAllElements(adornedElementModelItem, siblingsProperty.Collection);
                }
            }

        }

    }
}
